#ifndef CFG_V4_H
#define CFG_V4_H

#include "common.h"
#include "dist.h"
#include <stdlib.h>

#define FUNC_U64(name, op, ratio, rt)                                          \
  static rt _F_##name() { return get_smp_interval() op ratio; }

#if WRIST == 1
#define N3_HR_SD_THRESHOLD 2.0
#define SLEEP_MOTION_AVG_THRESHOLD (get_smp_interval() * 8)
#define SLEEP_HR_AVG_THRESHOLD 90
#define FIND_WAKE_MOTION_AVERAGE (get_smp_interval() * 4.0)
#define FIND_SLEEP_MOTION_THRESHOLD (get_smp_interval() * 10)
#define N3_MOTION_THRESHOLD (get_smp_interval() * 0)
// #define N1_MOTION_THRESHOLD (get_smp_interval() * 3.5)
#define WAKE_MOTION_THRESHOLD (get_smp_interval() * 8.0)
#define SLEEP_WAKE_STEPS_DIFF_THRESHOLD (get_smp_interval() * 2)
#define SLEEP_WAKE_MOTION_THRESHOLD (get_smp_interval() * 12)
#define FIND_SLEEP_MOTION_AVERAGE (get_smp_interval() * 3.0)
#define FIND_WAKE_MOTION_THRESHOLD (get_smp_interval() * 14)
#define WAKE_STEPS_THRESHOLD (get_smp_interval() * 1.0)
#define N3_HR_THRESHOLD 80
#define STAGING_LIGHT_SLEEP_TIME (30 * 60 * 1000)
#define CHECK_ACCELERATION_TIME (2 * 60 * 60 * 1000)

#define FIND_SLEEP_STEPS_DIFF_THRESHOLD (get_smp_interval() * 1.0)
#define FIND_WAKE_STEPS_DIFF_THRESHOLD (get_smp_interval() * 1.0)
#define FIND_SLEEP_STEPS_DIFF_THRESHOLD_LAX (get_smp_interval() * 1.0)
#define FIND_WAKE_STEPS_DIFF_THRESHOLD_LAX (get_smp_interval() * 1.0)
#define FIND_SLEEP_MOTION_AVERAGE_LAX (get_smp_interval() * 3.0)
#define FIND_WAKE_MOTION_THRESHOLD_LAX (get_smp_interval() * 14)
#define FIND_SLEEP_MOTION_THRESHOLD_LAX (get_smp_interval() * 10)

#else
#define N3_HR_SD_THRESHOLD 4.0
#define SLEEP_MOTION_AVG_THRESHOLD (get_smp_interval() * 14)
#define SLEEP_HR_AVG_THRESHOLD 100
#define FIND_WAKE_MOTION_AVERAGE (get_smp_interval() * 7.0)
#define FIND_SLEEP_MOTION_THRESHOLD (get_smp_interval() * 16)
#define N3_MOTION_THRESHOLD (get_smp_interval() * 1)
// #define N1_MOTION_THRESHOLD (get_smp_interval() * 5.0)
#define WAKE_MOTION_THRESHOLD (get_smp_interval() * 16.0)
#define SLEEP_WAKE_STEPS_DIFF_THRESHOLD (get_smp_interval() * 6)
#define SLEEP_WAKE_MOTION_THRESHOLD (get_smp_interval() * 24)
#define FIND_SLEEP_MOTION_AVERAGE (get_smp_interval() * 6.0)
#define FIND_WAKE_MOTION_THRESHOLD (get_smp_interval() * 16)
#define WAKE_STEPS_THRESHOLD (get_smp_interval() * 3.0)
#define N3_HR_THRESHOLD 90
#define STAGING_LIGHT_SLEEP_TIME (30 * 60 * 1000)
#define CHECK_ACCELERATION_TIME (2 * 60 * 60 * 1000)

#define FIND_SLEEP_STEPS_DIFF_THRESHOLD (get_smp_interval() * 3.0)
#define FIND_WAKE_STEPS_DIFF_THRESHOLD (get_smp_interval() * 5.0)
#define FIND_SLEEP_STEPS_DIFF_THRESHOLD_LAX (get_smp_interval() * 4.0)
#define FIND_WAKE_STEPS_DIFF_THRESHOLD_LAX (get_smp_interval() * 6.0)
#define FIND_SLEEP_MOTION_AVERAGE_LAX (get_smp_interval() * 7.0)
#define FIND_WAKE_MOTION_THRESHOLD_LAX (get_smp_interval() * 20)
#define FIND_SLEEP_MOTION_THRESHOLD_LAX (get_smp_interval() * 20)

#endif

#define MIN_STAGING_TIME (30 * 60 * 1000)

#define SLEEP_STEPS_DIFF_THRESHOLD (get_smp_interval() * 10)
#define MIN_JUDGMENT_SLEEP_TIME_20 20

#define SEGMENTED_CALCULATION_TIME (20 + 1)
#define FIND_SLEEP_POINT_LAX_MODE_TIME (2 * 60 * 60 * 1000)
#define FIND_SLEEP_POINT_LAX_MODE_TIME_2 (30 * 60 * 1000)

size_t raw_start_end(size_t begin, size_t end, const seg_info_t *results,
                     size_t len_result, ssize_t last_end,
                     linked_list_t *v4_list);

#define SLEEP_START_END_CAL_NEW()                                              \
  last_end = (ssize_t)raw_start_end(begin, end, seg_results, len_result,       \
                                    last_end, v4_list);

#define POST_CALL_START_END_IMPL()                                             \
  NOTUSED(index_start);                                                        \
  NOTUSED(index_end);                                                          \
  uint32_t v4_len;                                                             \
  sleep_start_end_t *se_list = (sleep_start_end_t *)iter_copy(                 \
      v4_list, sizeof(sleep_start_end_t), &v4_len, NULL);                      \
  free_items(v4_list, NULL, 0, NULL);                                          \
  size_t out_start, out_end;                                                   \
  uint64_t last_end_time = 0;                                                  \
  uint8_t lax_mode = 0;                                                        \
  for (uint32_t i = 0; i < v4_len; i++) {                                      \
    sleep_start_end_t *cur = se_list + i;                                      \
    lax_mode =                                                                 \
        (hr_list + cur->end_index)->ts - (hr_list + cur->start_index)->ts >=   \
            FIND_SLEEP_POINT_LAX_MODE_TIME ||                                  \
        ((hr_list + cur->start_index)->ts - last_end_time <=                   \
             FIND_SLEEP_POINT_LAX_MODE_TIME_2 &&                               \
         (hr_list + cur->end_index)->ts - (hr_list + cur->start_index)->ts >   \
             30 * 60 * 1000);                                                  \
    NOTUSED(lax_mode);                                                         \
    if (_dist->find_sleep_start_end_impl(!lax_mode, hr_list, count,            \
                                         cur->start_index, cur->end_index,     \
                                         &out_start, &out_end)) {              \
      sleep_start_end_t *obj =                                                 \
          (sleep_start_end_t *)malloc(sizeof(sleep_start_end_t));              \
      obj->start_index = out_start;                                            \
      obj->end_index = out_end;                                                \
      last_end_time = (hr_list + cur->end_index)->ts;                          \
      append_item(sleep_list, obj, NULL);                                      \
    }                                                                          \
  }                                                                            \
  free(se_list);

#endif